package com.example.vault.controller;

import com.example.vault.annotation.DataSource;
import com.example.vault.config.DynamicDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

/**
 * 多数据源管理控制器
 * 提供数据源连接测试、状态监控和管理功能
 */
@RestController
@RequestMapping("/multi-datasource")
public class MultiDataSourceController {

    @Autowired
    @Qualifier("transactionJdbcTemplate")
    private JdbcTemplate transactionJdbcTemplate;

    @Autowired
    @Qualifier("userJdbcTemplate")
    private JdbcTemplate userJdbcTemplate;

    @Autowired
    @Qualifier("logJdbcTemplate")
    private JdbcTemplate logJdbcTemplate;

    @Autowired
    @Qualifier("transactionMasterDataSource")
    private DataSource transactionMasterDataSource;

    @Autowired
    @Qualifier("transactionSlaveDataSource")
    private DataSource transactionSlaveDataSource;

    @Autowired
    @Qualifier("userMasterDataSource")
    private DataSource userMasterDataSource;

    @Autowired
    @Qualifier("userSlaveDataSource")
    private DataSource userSlaveDataSource;

    @Autowired
    @Qualifier("logMasterDataSource")
    private DataSource logMasterDataSource;

    @Autowired
    @Qualifier("logSlaveDataSource")
    private DataSource logSlaveDataSource;

    /**
     * 获取所有数据源状态概览
     */
    @GetMapping("/status")
    public ResponseEntity<Map<String, Object>> getAllDataSourceStatus() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            Map<String, Object> transactionStatus = new HashMap<>();
            transactionStatus.put("master", testDataSourceConnection(transactionMasterDataSource, "交易库主库"));
            transactionStatus.put("slave", testDataSourceConnection(transactionSlaveDataSource, "交易库从库"));
            
            Map<String, Object> userStatus = new HashMap<>();
            userStatus.put("master", testDataSourceConnection(userMasterDataSource, "用户库主库"));
            userStatus.put("slave", testDataSourceConnection(userSlaveDataSource, "用户库从库"));
            
            Map<String, Object> logStatus = new HashMap<>();
            logStatus.put("master", testDataSourceConnection(logMasterDataSource, "日志库主库"));
            logStatus.put("slave", testDataSourceConnection(logSlaveDataSource, "日志库从库"));
            
            result.put("status", "success");
            result.put("message", "多数据源状态检查完成");
            result.put("transaction", transactionStatus);
            result.put("user", userStatus);
            result.put("log", logStatus);
            result.put("timestamp", System.currentTimeMillis());
            
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            result.put("status", "error");
            result.put("message", "多数据源状态检查失败: " + e.getMessage());
            result.put("error", e.getClass().getSimpleName());
            result.put("timestamp", System.currentTimeMillis());
            return ResponseEntity.status(500).body(result);
        }
    }

    /**
     * 测试交易库连接
     */
    @GetMapping("/transaction/test")
    @DataSource(value = DynamicDataSource.DataSourceType.MASTER, database = "transaction")
    public ResponseEntity<Map<String, Object>> testTransactionDatabase() {
        return testDatabaseConnection(transactionJdbcTemplate, "交易库");
    }

    /**
     * 测试用户库连接
     */
    @GetMapping("/user/test")
    @DataSource(value = DynamicDataSource.DataSourceType.MASTER, database = "user")
    public ResponseEntity<Map<String, Object>> testUserDatabase() {
        return testDatabaseConnection(userJdbcTemplate, "用户库");
    }

    /**
     * 测试日志库连接
     */
    @GetMapping("/log/test")
    @DataSource(value = DynamicDataSource.DataSourceType.MASTER, database = "log")
    public ResponseEntity<Map<String, Object>> testLogDatabase() {
        return testDatabaseConnection(logJdbcTemplate, "日志库");
    }

    /**
     * 获取交易库详细信息
     */
    @GetMapping("/transaction/info")
    public ResponseEntity<Map<String, Object>> getTransactionDatabaseInfo() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            Map<String, Object> masterInfo = getDatabaseInfo(transactionMasterDataSource, "交易库主库");
            Map<String, Object> slaveInfo = getDatabaseInfo(transactionSlaveDataSource, "交易库从库");
            
            result.put("status", "success");
            result.put("message", "交易库信息获取成功");
            result.put("master", masterInfo);
            result.put("slave", slaveInfo);
            result.put("timestamp", System.currentTimeMillis());
            
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            result.put("status", "error");
            result.put("message", "获取交易库信息失败: " + e.getMessage());
            result.put("error", e.getClass().getSimpleName());
            result.put("timestamp", System.currentTimeMillis());
            return ResponseEntity.status(500).body(result);
        }
    }

    /**
     * 获取用户库详细信息
     */
    @GetMapping("/user/info")
    public ResponseEntity<Map<String, Object>> getUserDatabaseInfo() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            Map<String, Object> masterInfo = getDatabaseInfo(userMasterDataSource, "用户库主库");
            Map<String, Object> slaveInfo = getDatabaseInfo(userSlaveDataSource, "用户库从库");
            
            result.put("status", "success");
            result.put("message", "用户库信息获取成功");
            result.put("master", masterInfo);
            result.put("slave", slaveInfo);
            result.put("timestamp", System.currentTimeMillis());
            
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            result.put("status", "error");
            result.put("message", "获取用户库信息失败: " + e.getMessage());
            result.put("error", e.getClass().getSimpleName());
            result.put("timestamp", System.currentTimeMillis());
            return ResponseEntity.status(500).body(result);
        }
    }

    /**
     * 获取日志库详细信息
     */
    @GetMapping("/log/info")
    public ResponseEntity<Map<String, Object>> getLogDatabaseInfo() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            Map<String, Object> masterInfo = getDatabaseInfo(logMasterDataSource, "日志库主库");
            Map<String, Object> slaveInfo = getDatabaseInfo(logSlaveDataSource, "日志库从库");
            
            result.put("status", "success");
            result.put("message", "日志库信息获取成功");
            result.put("master", masterInfo);
            result.put("slave", slaveInfo);
            result.put("timestamp", System.currentTimeMillis());
            
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            result.put("status", "error");
            result.put("message", "获取日志库信息失败: " + e.getMessage());
            result.put("error", e.getClass().getSimpleName());
            result.put("timestamp", System.currentTimeMillis());
            return ResponseEntity.status(500).body(result);
        }
    }

    /**
     * 测试读写分离功能
     */
    @GetMapping("/test-read-write-separation")
    public ResponseEntity<Map<String, Object>> testReadWriteSeparation() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 测试写操作（主库）
            Map<String, Object> writeTest = testWriteOperation();
            
            // 测试读操作（从库）
            Map<String, Object> readTest = testReadOperation();
            
            result.put("status", "success");
            result.put("message", "读写分离测试完成");
            result.put("writeTest", writeTest);
            result.put("readTest", readTest);
            result.put("timestamp", System.currentTimeMillis());
            
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            result.put("status", "error");
            result.put("message", "读写分离测试失败: " + e.getMessage());
            result.put("error", e.getClass().getSimpleName());
            result.put("timestamp", System.currentTimeMillis());
            return ResponseEntity.status(500).body(result);
        }
    }

    /**
     * 测试写操作（主库）
     */
    @DataSource(value = DynamicDataSource.DataSourceType.MASTER, database = "transaction")
    private Map<String, Object> testWriteOperation() {
        Map<String, Object> result = new HashMap<>();
        try {
            // 模拟写操作
            String currentTime = transactionJdbcTemplate.queryForObject("SELECT NOW()", String.class);
            result.put("operation", "write");
            result.put("dataSource", "master");
            result.put("currentTime", currentTime);
            result.put("success", true);
        } catch (Exception e) {
            result.put("operation", "write");
            result.put("dataSource", "master");
            result.put("error", e.getMessage());
            result.put("success", false);
        }
        return result;
    }

    /**
     * 测试读操作（从库）
     */
    @DataSource(value = DynamicDataSource.DataSourceType.SLAVE, database = "transaction")
    private Map<String, Object> testReadOperation() {
        Map<String, Object> result = new HashMap<>();
        try {
            // 模拟读操作
            String currentTime = transactionJdbcTemplate.queryForObject("SELECT NOW()", String.class);
            result.put("operation", "read");
            result.put("dataSource", "slave");
            result.put("currentTime", currentTime);
            result.put("success", true);
        } catch (Exception e) {
            result.put("operation", "read");
            result.put("dataSource", "slave");
            result.put("error", e.getMessage());
            result.put("success", false);
        }
        return result;
    }

    /**
     * 测试数据库连接
     */
    private ResponseEntity<Map<String, Object>> testDatabaseConnection(JdbcTemplate jdbcTemplate, String databaseName) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            String currentTime = jdbcTemplate.queryForObject("SELECT NOW()", String.class);
            
            result.put("status", "success");
            result.put("message", databaseName + "连接测试成功");
            result.put("currentTime", currentTime);
            result.put("timestamp", System.currentTimeMillis());
            
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            result.put("status", "error");
            result.put("message", databaseName + "连接测试失败: " + e.getMessage());
            result.put("error", e.getClass().getSimpleName());
            result.put("timestamp", System.currentTimeMillis());
            return ResponseEntity.status(500).body(result);
        }
    }

    /**
     * 测试数据源连接
     */
    private Map<String, Object> testDataSourceConnection(DataSource dataSource, String name) {
        Map<String, Object> result = new HashMap<>();
        
        try (Connection connection = dataSource.getConnection()) {
            boolean isValid = connection.isValid(5);
            result.put("name", name);
            result.put("status", isValid ? "connected" : "disconnected");
            result.put("url", connection.getMetaData().getURL());
            result.put("username", connection.getMetaData().getUserName());
        } catch (SQLException e) {
            result.put("name", name);
            result.put("status", "error");
            result.put("error", e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取数据库详细信息
     */
    private Map<String, Object> getDatabaseInfo(DataSource dataSource, String name) throws SQLException {
        Map<String, Object> result = new HashMap<>();
        
        try (Connection connection = dataSource.getConnection()) {
            DatabaseMetaData metaData = connection.getMetaData();
            
            result.put("name", name);
            result.put("databaseProductName", metaData.getDatabaseProductName());
            result.put("databaseProductVersion", metaData.getDatabaseProductVersion());
            result.put("driverName", metaData.getDriverName());
            result.put("driverVersion", metaData.getDriverVersion());
            result.put("url", metaData.getURL());
            result.put("username", metaData.getUserName());
            result.put("maxConnections", metaData.getMaxConnections());
            result.put("supportsTransactions", metaData.supportsTransactions());
        }
        
        return result;
    }
}